package org.eiahe.hr.performance.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.BeanUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.system.domain.HrEmployee;
import org.ehe.system.domain.vo.HrEmployeeVo;
import org.ehe.system.domain.vo.SysUserVo;
import org.ehe.system.mapper.SysUserMapper;
import org.ehe.system.service.IHrEmployeeService;
import org.ehe.system.service.ISysUserService;
import org.eiahe.hr.performance.domain.PerformanceIndicator;
import org.eiahe.hr.performance.domain.PerformancePositionIndicator;
import org.eiahe.hr.performance.domain.PerformanceScoreDetail;
import org.eiahe.hr.performance.domain.PerformanceScorer;
import org.eiahe.hr.performance.domain.bo.PerformanceScoreDetailBo;
import org.eiahe.hr.performance.domain.vo.PerformanceScoreDetailVo;
import org.eiahe.hr.performance.event.PerformanceScoreDetailUpdatedEvent;
import org.eiahe.hr.performance.mapper.PerformanceIndicatorMapper;
import org.eiahe.hr.performance.mapper.PerformanceScoreDetailMapper;
import org.eiahe.hr.performance.mapper.PerformanceScorerMapper;
import org.eiahe.hr.performance.service.IPerformanceScoreDetailService;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.ApplicationContext;
import org.ehe.common.core.utils.SpringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 绩效评分明细Service业务层处理
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@Service
public class PerformanceScoreDetailServiceImpl implements IPerformanceScoreDetailService {

    private final PerformanceScoreDetailMapper baseMapper;
    private final PerformanceIndicatorMapper performanceIndicatorMapper;
    private final ISysUserService userService;
    private final IHrEmployeeService employeeService;
    private final PerformanceScorerMapper scorerMapper;

    @Override
    public PerformanceScoreDetailVo queryById(Long detailId) {
        PerformanceScoreDetailVo performanceScoreDetailVo = baseMapper.selectVoById(detailId);
        SysUserVo sysUserVo = userService.selectUserByUserName(performanceScoreDetailVo.getScorer());
        if (Objects.nonNull(sysUserVo)) {
            performanceScoreDetailVo.setScorerName(sysUserVo.getNickName());
        }
        return performanceScoreDetailVo;
    }

    private LambdaQueryWrapper<PerformanceScoreDetail> buildQueryWrapper(PerformanceScoreDetailBo detail) {
        LambdaQueryWrapper<PerformanceScoreDetail> lqw = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(detail.getIndicatorName())) {
            List<PerformanceIndicator> indicators = performanceIndicatorMapper
                    .selectList(new LambdaQueryWrapper<PerformanceIndicator>()
                            .like(PerformanceIndicator::getIndicatorName, detail.getIndicatorName()));
            if (CollUtil.isNotEmpty(indicators)) {
                List<Long> indids = indicators.stream().map(PerformanceIndicator::getIndicatorId)
                        .collect(Collectors.toList());
                lqw.in(PerformanceScoreDetail::getIndicatorId, indids);
            } else {
                lqw.eq(PerformanceScoreDetail::getIndicatorId, -1);
            }
        }
        lqw.eq(StringUtils.isNotBlank(detail.getDelFlag()), PerformanceScoreDetail::getDelFlag, detail.getDelFlag());
        return lqw;
    }

    @Override
    public TableDataInfo<PerformanceScoreDetailVo> queryPageListVo(PerformanceScoreDetailBo detail,
            PageQuery pageQuery) {
        LambdaQueryWrapper<PerformanceScoreDetail> lqw = buildQueryWrapper(detail);
        Page<PerformanceScoreDetailVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);
        page.getRecords().forEach(p -> {
            HrEmployeeVo hrEmployeeVo = employeeService.queryByEmployeeNo(p.getScorer());
            if (Objects.nonNull(hrEmployeeVo)) {
                p.setScorerName(hrEmployeeVo.getEmployeeName());
            }
            Long indicatorId = p.getIndicatorId();
            PerformanceIndicator performanceIndicator = performanceIndicatorMapper.selectById(indicatorId);
            if(Objects.nonNull(performanceIndicator)){
                p.setIndicatorName(performanceIndicator.getIndicatorName());
            }
        });
        return TableDataInfo.build(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(PerformanceScoreDetailBo detail) {
        // 判断是新增还是修改
        if (StringUtils.isNotBlank(detail.getScorer())) {
            HrEmployee hrEmployee = employeeService.queryByUserId(Long.valueOf(detail.getScorer()));
            if (Objects.nonNull(hrEmployee)) {
                detail.setScorer(hrEmployee.getEmployeeNo());
            }
        }
        PerformanceScoreDetail existDetail = this.baseMapper.selectOne(new LambdaQueryWrapper<PerformanceScoreDetail>()
                .eq(PerformanceScoreDetail::getScoreId, detail.getScoreId())
                .eq(PerformanceScoreDetail::getIndicatorId, detail.getIndicatorId())
                .eq(PerformanceScoreDetail::getScorer, detail.getScorer()));
        if (Objects.nonNull(existDetail)) {
            detail.setDetailId(existDetail.getDetailId());
            // 获取指标权重
            LambdaQueryWrapper<PerformanceScorer> weightLqw = Wrappers.lambdaQuery();
            weightLqw.eq(PerformanceScorer::getEmployeeNo, detail.getScorer());
            PerformanceScorer weight = scorerMapper.selectOne(weightLqw);

            if (weight != null) {
                detail.setWeight(weight.getWeight());
                // 计算加权得分
                BigDecimal weightedScore = detail.getScore()
                    .multiply(weight.getWeight())
                    .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
                detail.setWeightedScore(weightedScore);
            }

            return this.updateByBo(detail);
        }
        PerformanceScoreDetail add = MapstructUtils.convert(detail, PerformanceScoreDetail.class);
        if (StringUtils.isBlank(add.getScorer())) {
            add.setScorer(LoginHelper.getUsername());
        }
        return baseMapper.insert(add) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(PerformanceScoreDetailBo detail) {
        PerformanceScoreDetail scoreDetail = this.baseMapper.selectById(detail.getDetailId());
        scoreDetail.setScore(detail.getScore());
        scoreDetail.setWeight(detail.getWeight());
        scoreDetail.setWeightedScore(detail.getWeightedScore());
        scoreDetail.setUpdateBy(LoginHelper.getUserId());
        scoreDetail.setUpdateTime(new Date());
        boolean result = baseMapper.updateById(scoreDetail) > 0;

        // 如果更新成功且分数不为空，触发评分明细更新事件
        if (result && scoreDetail.getScore() != null) {
            SpringUtils.context().publishEvent(
                    new PerformanceScoreDetailUpdatedEvent(this, detail, scoreDetail.getScorer(),
                            scoreDetail.getDetailId(), scoreDetail.getResultId()));
        }

        return result;
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (ids == null || ids.isEmpty()) {
            return false;
        }
        if (isValid) {
            // 校验逻辑可以根据需要添加
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<PerformanceScoreDetailVo> queryListByResultId(Long resultId) {
        LambdaQueryWrapper<PerformanceScoreDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceScoreDetail::getResultId, resultId);
        lqw.eq(PerformanceScoreDetail::getDelFlag, "0");
        lqw.orderByAsc(PerformanceScoreDetail::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }

    @Override
    public List<PerformanceScoreDetailVo> queryListByResultIdAndScorer(Long resultId, String scorer) {
        LambdaQueryWrapper<PerformanceScoreDetail> lqw = Wrappers.lambdaQuery();
        lqw.eq(PerformanceScoreDetail::getResultId, resultId);
        lqw.eq(PerformanceScoreDetail::getScorer, scorer);
        lqw.eq(PerformanceScoreDetail::getDelFlag, "0");
        lqw.orderByAsc(PerformanceScoreDetail::getCreateTime);
        return baseMapper.selectVoList(lqw);
    }
}
